#pragma once
#include <iostream>
#include <assert.h>
using namespace std;
namespace wang
{
	class String
	{
	public:
		//迭代器,当然也可以使用using
		//typedef char* iterator;
		using iterator = char*;
		using const_iterator = const char*;
		//无参构造
		//String();
		//带参的构造
		/*
		无参构造和带参的构造其实可以合并成一个构造,那
		就是提供全缺省参数,但是这里提供全缺省参数不能
		直接给nullptr,这样程序会崩溃。
		给""就可以,因为里面默认有'\0'
		*/
		String(const char* str = "");
		const char* c_str() const;
		size_t size() const;
		//修改
		char& operator[](size_t i);
		const char& operator[](size_t i) const;
		//析构函数
		~String();
		//拷贝构造
		String(const String& s);
		//迭代器
		iterator begin();
		iterator end();
		//const迭代器 - 自身可以++,但是指向的内容不能++
		const_iterator begin() const;
		const_iterator end() const;
		void reserve(size_t n);
		void push_back(char ch);
		void append(const char* str);
		String& operator+=(char ch);
		String& operator+=(const char* str);
		void insert(size_t pos, char ch);
		void insert(size_t pos, const char* str);
		void erase(size_t pos, size_t len = npos);
		size_t find(char ch, size_t pos = 0);
		size_t find(const char* str, size_t pos = 0);
		String substr(size_t pos,size_t len = npos);
		String& operator= (String s);
		void clear();
		void swap(String& s);
	private:
		char* _str;
		int _size;
		int _capacity;
	public:
		//声明npos
		//静态成员变量在这里不能给缺省值的,必须在定义的时候、
		//初始化,但是const类型的静态成员变量在这里可以给缺省值
		//这里给缺省值和给上面的给缺省值是不一样的,上面给缺省值
		//是给初始化列表的,而这个这样写就可以理解为一种定义,可以
		//认为是一种特殊处理
		//static const size_t npos = -1;
		//只针对整型才可以,别的类型不可以
		//static const double dd = 2.2;

		//其实不建议这样写,声明和定义正常分离就行
		static const size_t npos;
	};
	void swap(String& s1,String& s2);
	int StrCmp(const char* str1, const char* str2);
	bool operator== (const String& lhs, const String& rhs);
	bool operator!= (const String& lhs, const String& rhs);
	bool operator> (const String& lhs, const String& rhs);
	bool operator< (const String& lhs, const String& rhs);
	bool operator>= (const String& lhs, const String& rhs);
	bool operator<= (const String& lhs, const String& rhs);
	ostream& operator<< (ostream& out, const String& str);
	istream& operator>> (istream& in, String& str);
	istream& getline (istream& in, String& str, char delim = '\n');
}
